package spaska.data.readers;

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;

import spaska.data.Attribute;
import spaska.data.Attribute.ValueType;
import spaska.data.Dataset;
import spaska.data.Instance;
import spaska.data.NumericValue;
import spaska.data.Value;

public class NominalToNumericValidator implements Validator {

	private Dataset dataset;

	@Override
	public void setParameters(Map<String, String> parameters) {
	}

	/**
	 * @param dataset the dataset to set
	 */
	public void setDataset(Dataset dataset) {
		this.dataset = dataset;
	}

	@Override
	public boolean validate(Dataset dataset) {
		this.dataset = dataset;
		for (int i = 0; i < dataset.getAttributesCount(); i++) {
			Attribute a = dataset.getAttribute(i);
			if (a.getType().equals(ValueType.Nominal)) {
				convertAttribute(i);				
			}
		}
		return false;
	}

	public LinkedHashMap<Value, Value> getLegend(int attrIdx) {
		Attribute attr = dataset.getAttribute(attrIdx);
		LinkedHashMap<Value, Value> legend = new LinkedHashMap<Value, Value>();
		if (attr.getType().equals(Attribute.ValueType.Nominal)) {
			int i = 0;
			for (Value v : dataset.getDomain(attr)) {
				legend.put(v, new NumericValue((double) i++));
			}
		}
		return legend;
	}

	public void convertAttribute(int attrIdx) {
		LinkedHashMap<Value, Value> legend = getLegend(attrIdx);

		Attribute originalAttr = dataset.getAttribute(attrIdx);
		Attribute newAttribute = new Attribute(originalAttr.getName(), ValueType.Numeric);
		dataset.getAttributes().set(attrIdx, newAttribute);

		dataset.setAttributeDomain(newAttribute, new LinkedHashSet<Value>(legend.values()));

		for (Instance i : dataset) {
			Value oldValue = i.valueAt(attrIdx);
			i.setValueAt(attrIdx, legend.get(oldValue));
		}
	}

}
